Skip to content

fix(astro-renderer): no dataDir in the cloudflare target's config (#239) - #240

Merged
Madraka merged 2 commits into
mainfrom
claude/datadir-guard-239
Nov 15, 2026
Merged

Madraka merged 2 commits into
mainfrom
claude/datadir-guard-239

Conversation

@Madraka

@Madraka Madraka commented Nov 15, 2026 •

Copy link
Copy Markdown
Contributor

What

RFC-0046 §11b classes cloudhal.json dataDir as runtime for deploy --release: the Site Worker never reads it. The integration still baked it in, though. astro:config:setup resolves dataDir to an absolute path and puts it into virtual:cloudhal/config on every target. So a release bundle built in CI carried the CI runner's absolute path to every deployment.

  • Fix (packages/astro-renderer/src/integration.ts): virtualConfig(resolved, cloudflare) drops dataDir from the virtual module on the cloudflare target. Node targets (cloudhal dev, static builds) keep it: runtime.ts, the comments middleware and the static-* writers read the local store from it.

  • Why nothing on the cloudflare target needs it:

    • every reader imports @cloudhal/astro-renderer/runtime, which resolves to runtime-workerd.ts under the workerd condition, and that file ignores dataDir (bindings decide);
    • the media, comments and dev middleware aren't added on that target;
    • astro:build:done returns before the static-* writers.

    The workerd suites below confirm it.

Tests (run alone, one at a time; load stayed below 5.2)

  • astro-renderer/test/virtual-config.test.ts (new, 2 tests): it runs astro:config:setup and loads the virtual module.
    • On cloudflare the module has no dataDir and no path, for a relative, an absolute and another dataDir, and it is the same bytes for each.
    • On node the module keeps the resolved path.
  • cli/test/cloudflare-datadir.test.ts (new, 3 tests, real starter builds and workerd):
    • two builds that differ only in dataDir (.cloudhal, then a nonexistent absolute path) are the same bytes across all 112 files;
    • neither path appears in any built file;
    • the built Worker, on wrangler's test harness with local D1 and R2, serves / and /posts/hello-world after the data directory has been moved off disk.
    • Without the fix, the first two tests fail (checked by reverting the one line).
    • Astro writes a random per-build manifest key (it encrypts server-island and action props) unless ASTRO_KEY is set. The test pins it, so the two builds can be compared. With the key pinned, the build is deterministic.
  • Existing suites:
    • astro-renderer full suite: 54 files, 388 tests;
    • the cli workerd suites, alone: cloudflare 10, cloudflare-deploy 3, cloudflare-gates 9, cloudflare-analytics 9, cloudflare-comments 8, cloudflare-status 6, cloudflare-multisite 6, cloudflare-schedules 4;
    • tsc for astro-renderer and cli, biome and size:check are clean. The one lint warning is the existing complexity of the astro:config:setup hook, which is 32 on main too.

Review round 1

  • Types. virtual:cloudhal/config is now typed as VirtualCloudhalConfig (Omit<CloudhalRendererConfig, "dataDir"> & { dataDir?: string }, exported), the same shape virtualConfig returns. Both declarations use it: astro-renderer's astro-env.d.ts and the starter's src/env.d.ts. So theme code that reads dataDir must handle its absence.
    • getSource and peerEditions (both runtimes) take that type.
    • The Node-only paths that need dataDir say so when it is missing, instead of reading undefined: nodeDataDir in runtime.ts, and the comments middleware.
  • Wording. RFC §11b and the changeset now say no dataDir path reaches a bundle. They note that Astro's own serialized manifest still carries its root, source and output directories as file:// URLs.
  • Reproducibility. RFC §11b says that bundles are not byte-reproducible, by design. Astro's random per-build key, which encrypts server-island and action props, stays unpinned in the release build, because a fixed key would be published in every tarball. Trust rests on the signature and the attestation. Only this test pins ASTRO_KEY, to compare its two builds.
  • Test. cloudflare-datadir.test.ts now scans the first build for its own data path before the second build replaces dist.
  • Re-run, one at a time:
    • turbo run typecheck: 22/22;
    • astro-renderer full suite: 55 files, 390 tests;
    • cli: cloudflare-datadir 3, cloudflare 10, release-theme-check 8, deploy-release 24;
    • demo:archive --check, size and biome are clean.

RFC-0046 §11b now cites this guard. Changeset: @cloudhal/astro-renderer patch.

Closes #239

🤖 Generated with Claude Code

RFC-0046 §11b classes cloudhal.json dataDir as runtime: the Site Worker reads
D1 and R2 through its bindings (runtime-workerd.ts ignores the field), but the
integration still baked the resolved value, the build machine's absolute
path, into virtual:cloudhal/config, so a release bundle built in CI carried
it to every deployment. The cloudflare target now gets the config without
dataDir (virtualConfig); Node targets keep it.

- astro-renderer test: the module has no dataDir on cloudflare, whatever
  cloudhal.json says, and keeps it on node.
- cli workerd test: two starter builds that differ only in dataDir are the
  same bytes (Astro's per-build key pinned with ASTRO_KEY), neither carries
  the path, and the built Worker serves the site with no data directory on
  disk. Without the fix the first two fail.
- RFC-0046 §11b cites the guard.

Closes #239

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Madraka <[email protected]>
@Madraka
Madraka force-pushed the claude/datadir-guard-239 branch from 3c8870f to 4cb3ac6 Compare November 15, 2026 07:04
- virtual:cloudhal/config is typed VirtualCloudhalConfig (dataDir optional,
  exported) in astro-renderer's astro-env.d.ts and the starter's env.d.ts;
  getSource and peerEditions take it, and the Node paths that need dataDir
  say so when it is missing (nodeDataDir, the comments middleware).
- RFC-0046 §11b and the changeset say no dataDir path reaches a bundle
  (Astro's own manifest still carries its root, src and out URLs), and that
  bundles are not byte-reproducible by design: Astro's random per-build key
  stays unpinned in the release build, as a fixed one would be published.
- cloudflare-datadir.test scans the first build for its own path before the
  second build replaces dist.

Refs #239

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Madraka <[email protected]>
@Madraka
Madraka merged commit 8887243 into main Nov 15, 2026
10 checks passed
@Madraka
Madraka deleted the claude/datadir-guard-239 branch November 15, 2026 07:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

release: drift guard that the cloudflare target ignores dataDir (RFC-0046 §11b)

1 participant